﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using System.Web.Http;
using Newtonsoft.Json;
using NCS.IConnect.Core.Utilities;

namespace NCS.IConnect.Core.WebApi.Description
{
    /// <summary>
    /// HttpController specific descriptor.
    /// </summary>
    public class ApiControllerDescriptor
    {
        /// <summary>
        /// Gets the <see cref="HttpControllerDescriptor"/>.
        /// </summary>
        /// <value>The <see cref="HttpControllerDescriptor"/>.</value>
        [JsonIgnore]
        public HttpControllerDescriptor HttpControllerDescriptor { get; private set; }


        /// <summary>
        /// Gets the documentation provider.
        /// </summary>
        /// <value>The documentation provider.</value>
        [JsonIgnore]
        public IDocumentationProvider DocumentationProvider { get; private set; }

        /// <summary>
        /// Get the Url prefix.
        /// </summary>
        public string UrlPrefix { get; private set; }

        /// <summary>
        /// Gets the name of the controller.
        /// </summary>
        /// <value>The name of the controller.</value>
        public string ControllerName { get; private set; }


        /// <summary>
        /// Gets the description of controller.
        /// </summary>
        /// <value>The description of controller.</value>
        public string Description { get; private set; }

        /// <summary>
        /// Gets <see cref="ApiActionDescriptor"/>s to describe all actions.
        /// </summary>
        /// <value>The <see cref="ApiActionDescriptor"/>s to describe all actions.</value>
        public ApiActionDescriptor[] ActionDescriptors { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="ApiControllerDescriptor"/> class.
        /// </summary>
        /// <param name="httpControllerDescriptor">The HTTP controller descriptor.</param>
        /// <param name="documentationProvider">The documentation provider.</param>
        public ApiControllerDescriptor(HttpControllerDescriptor httpControllerDescriptor, IDocumentationProvider documentationProvider)
        {
            Guard.ArgumentNotNull(httpControllerDescriptor, "httpControllerDescriptor");
            Guard.ArgumentNotNull(documentationProvider, "documentationProvider");

            this.HttpControllerDescriptor = httpControllerDescriptor;
            this.DocumentationProvider = documentationProvider;
            this.Description = documentationProvider.GetDocumentation(this.HttpControllerDescriptor);
            this.ControllerName = httpControllerDescriptor.ControllerName;

            List<ApiActionDescriptor> actionDescriptors = new List<ApiActionDescriptor>();
            var httpActionDescriptors = httpControllerDescriptor.Configuration.Services.GetActionSelector()
                 .GetActionMapping(httpControllerDescriptor).SelectMany(m => m).ToArray();
            foreach (var httpActionDescriptor in httpActionDescriptors)
            {
                actionDescriptors.Add(new ApiActionDescriptor(this, httpActionDescriptor));
            }
            this.ActionDescriptors = actionDescriptors.OrderBy(it=>it.Request.Uri).ToArray();
            RoutePrefixAttribute attribute = httpControllerDescriptor.GetCustomAttributes<RoutePrefixAttribute>().First();
            this.UrlPrefix = attribute.Prefix;
        }
    }
}